﻿using System;
using Maestro_Proveedores;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Windows.Forms;

namespace Maestro_Proveedores.evaluacionDeDesempeno.indicadores
{
    /// <remarks>
    /// <para>El indicador tiene como objetivo evaluar la calidad del proveedor, de acuerdo al porcentaje de unidades entregadas satisfactoriamente conforme a los estándares de calidad durante la recepción de los pedidos.</para>
    /// <para>Este indicador se apoya en las devoluciones (VR) y los rechazos que se realizan en la corporacion, discrimiendo aquellos que sean atribuibles al proveedor.</para>
    /// </remarks>
    class CalidadProducto : Indicador
    {
        private MAPICS.MAPICSDataSet mAPICSdATAsET = new MAPICS.MAPICSDataSet();
        private MAPICS.MAPICSDataSetTableAdapters.INF_OCTableAdapter iNF_OCTableAdapter = new MAPICS.MAPICSDataSetTableAdapters.INF_OCTableAdapter();
        private MAPICS.MAPICSDataSetTableAdapters.INF_OC_CONSOLIDADOTableAdapter iNF_OC_CONSOLIDADOTableAdapter = new MAPICS.MAPICSDataSetTableAdapters.INF_OC_CONSOLIDADOTableAdapter();
        private _Maestro_Proveedores_CORPORATIVADataSetTableAdapters.PRV_DEVOLUCIONTableAdapter pRV_DEVOLUCIONTableAdapter = new _Maestro_Proveedores_CORPORATIVADataSetTableAdapters.PRV_DEVOLUCIONTableAdapter();
        private _Maestro_Proveedores_CORPORATIVADataSetTableAdapters.PRV_RECHAZO_por_OCTableAdapter pRV_RECHAZO_por_OCTableAdapter = new _Maestro_Proveedores_CORPORATIVADataSetTableAdapters.PRV_RECHAZO_por_OCTableAdapter();
        /// <summary>
        /// Cuando se crea una nueva instancia del indicador, se incializan todas sus variables y propiedades. Tanto las propias como las herededas de la clase Indicador
        /// </summary>
        public CalidadProducto()
        {
            this.Peso = 0.50;
            this.TipoIndicador = Enums.TipoIndicador.Bien;
        }
        /// <summary>
        /// Redefinicion del metodo toString()
        /// </summary>
        /// <returns>Nombre Completo del presente indicador</returns>
        public override string ToString()
        {
            return "Calidad del Producto";
        }
        /// <summary>
        /// redefinición del metodo Calcular(), declarado en la clase padre Indicador como un metodo abstracto (se debe redefinir obligatoriamente en cualquier clase que herede de la clase Indicador)
        /// </summary>
        /// <returns></returns>
        protected override bool calcular()
        {
            try
            {
                //--- obtengo los parametros y los datos
                decimal fechaInf = decimal.Parse(MAESTROS.ClassVarios.FechaMAPIC(this.FechaInferior));
                decimal fechaSup = decimal.Parse(MAESTROS.ClassVarios.FechaMAPIC(this.FechaSuperior));

                double total_porcentaje_calidad = 0; //--- devoluciones
                double total_porcentaje_calidad2 = 0; //-- rechazos
                double total_registros = 0; //-- devoluciones
                double total_registros2 = 0; //-- rechazos
                decimal temp =0;
                
            //--- calculo los porcentajes de devoluciones
                
                //--- aqui se trae la informacion desde INFOR
                this.iNF_OCTableAdapter.FillByCodProvFechas_Entrega(this.mAPICSdATAsET.INF_OC, this.registroProveedor.id_proveedor, fechaInf, fechaSup);
                
                foreach (MAPICS.MAPICSDataSet.INF_OCRow row in this.mAPICSdATAsET.INF_OC)
                {
                    string oc = MAESTROS.ClassVarios.LimpiarCadena(row.COD_OC);
                    
                //--DEVOLUCIONES

                    DateTime fechaEsperada = MAESTROS.ClassVarios.FechaMAPIC(row.FECHA_ENTR_R.ToString());
                    //--- aqui obtengo el total de articulos devueltos para cada registro de la orden de compra (VR's).
                    temp = decimal.Parse(this.pRV_DEVOLUCIONTableAdapter.Scalar_Sum_cantidadDevuelta_culpaProveedor2(oc, row.NUM_ITEM).ToString());
                    
                    //--- cancular el porcentaje de cantidades devueltas
                        if (row.ULT_REC.Equals(0))//--- si no se ha registrado fecha de entrada al sistema, entonces la fecha real sera la fecha de hoy 
                        {
                            DateTime fechaReal = DateTime.Parse(DateTime.Now.ToShortDateString());
                            //-- en caso de que no se halla registrado fecha de entrada, debo verificar si los dias de retraso exceden el maxim0o de dias de retrazos permitidos (Informacion suministrada por: Andrea GarciaHerreros)
                            if ((ConfiguracionDelSistema.DiasMaximosDeRetraso + (fechaEsperada - fechaReal).TotalDays) >= 0)//--si no excede el maximo de dias, entonces calculo el indicador
                            {
                                total_porcentaje_calidad += 1 - double.Parse((temp / row.CAN_SOL).ToString());
                                total_registros++;
                            }
                            else
                            {
                                //--- si se excede el maximo de dias permitidos, este ITEM se debe omitir de la evaluacion.
                            }
                        }
                        //-- si se registro una fecha de entrada al almacen, entonces ya no aplica lo del maximo de dias permitidos.
                        else
                        {
                            total_porcentaje_calidad += 1 - double.Parse((temp / row.CAN_SOL).ToString());
                            total_registros++;
                        }                                               
                }

                //--- si no hay registros, el indicador no aplica
                if (total_registros.Equals(0))
                {
                    return false;
                }
                else 
                {
                    total_porcentaje_calidad = (total_porcentaje_calidad / total_registros);
                }
            //--- calculo los porcentajes de rechazos

                //--- aqui se trae la informacion desde INFOR
                this.iNF_OC_CONSOLIDADOTableAdapter.FillByCodPRV_Fecha(this.mAPICSdATAsET._INF_OC_CONSOLIDADO, this.registroProveedor.id_proveedor, fechaInf, fechaSup);
                
                foreach (MAPICS.MAPICSDataSet._INF_OC_CONSOLIDADORow row in this.mAPICSdATAsET._INF_OC_CONSOLIDADO)
                {

                    string oc = MAESTROS.ClassVarios.LimpiarCadena(row.COD_OC);
                        //--- aqui obtengo el total de articulos rechazados para cada registro de la orden de compra.
                        string temp2 = this.pRV_RECHAZO_por_OCTableAdapter.Scalar_count_itemsRechazadosByOC(oc).ToString();
                        if (temp2.Equals(string.Empty))
                            temp = 0M;
                        else
                            temp = decimal.Parse(temp2);
                        //--- encontrar el total de articulos de esta orden
                        string temp3 = row.CANTIDAD.ToString();
                    
                        //--si la orden no tiene ITEMS, HAY un error en INFOR
                        if (temp3.Equals(string.Empty) || temp3.Equals("0")){
                            MessageBox.Show("ERROR!!!!\n\n La orden de compra "+oc+" No tiene articulos verifique esta orden.");
                        }
                        //-- calculo el porcentaje correspondiente
                        else{
                            temp = 1M-temp/decimal.Parse(temp3);
                        //--- calcular el porcentaje de cantidades rechazadas
                        total_porcentaje_calidad2 += double.Parse(temp.ToString());
                        total_registros2++;
                    }
                }


                //--- si no hay registros, el indicador no aplica
                if (total_registros2 == 0)
                {
                    return false;
                }
                else 
                {
                    total_porcentaje_calidad2 = total_porcentaje_calidad2 / total_registros2;
                }

                //--- aqui defino el valor final del indicador
                double total_calidad = 0;

                //-- si no hay devoluciones, pero si hay rechazos, entonces trabajo con los rechazos.
                if (total_porcentaje_calidad.Equals(1d) && !total_porcentaje_calidad2.Equals(1d)) {
                    total_calidad = total_porcentaje_calidad2;
                }
                //-- si no hay rechazos, pero si hay devoluciones, entonces trabajo con los rechazos.
                else if (!total_porcentaje_calidad.Equals(1d) && total_porcentaje_calidad2.Equals(1d))
                {
                    total_calidad = total_porcentaje_calidad;
                }
                //-- si hay devoluciones y rechazos, entonces trabajo el promedio.
                else if (!total_porcentaje_calidad.Equals(1d) && !total_porcentaje_calidad2.Equals(1d))
                {
                    total_calidad = (total_porcentaje_calidad + total_porcentaje_calidad2) / 2d;
                }
                //-- si no hay devoluciones ni rechazos, entonces la calidad es 100.
                else if (total_porcentaje_calidad.Equals(1d) && total_porcentaje_calidad2.Equals(1d))
                {
                    total_calidad = 1d;
                }
                //--- Guardo el resultado del indicador
                this.Resultado = total_calidad * 100;

                //--- calculo las cantidades faltantes promedio y aplico la definicion del Indicador (consultar Proyecto: sistema_gestion_de_proveedores_2009)

                if (this.Resultado >= 100)
                {
                    this.PorcentajeEvaluacion = 100;
                }
                else if (!this.registroProveedor.grupo_servicio.Contains("A -") && this.Resultado >= 97)
                {
                    this.PorcentajeEvaluacion = 100;
                }
                else if (this.Resultado >= 85)
                {
                    this.PorcentajeEvaluacion = 75;
                }
                else if (this.Resultado >= 70)
                {
                    this.PorcentajeEvaluacion = 50;
                }
                else
                {
                    this.PorcentajeEvaluacion = 25;
                }
                return true;
            }
            catch (SqlException ex)
            {
                Maestro_Proveedores.herramientas.MessageException.show(ex);
                return false;
            }
        }

    }
}